﻿using gCursorLib;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows.Forms;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Header;
using TreeView = System.Windows.Forms.TreeView;

namespace WindowsFormsApp1
{
    public partial class UserControl1 : UserControl
    {
        public Project mProj;
        /// <summary>拖拽时候的模块源,创建模块时候的源头要重新new一个模块</summary>
        private ModFlowItem mUiFrom;
        /// <summary>拖拽允许</summary>
        public bool mItemDragEnabled;
        /// <summary>当前选中的ModFlowItem</summary>
        private ModFlowItem mIsNowSelectedItem;
        /// <summary>模块单元的高度</summary>
        private int mItemHeight = 30;
        /// <summary>模块树结构</summary>
        private TreeView mTreeView;
        /// <summary>画布图像,所有自绘图像都是在此处绘制后贴在控件上</summary>
        private Bitmap mBuff;
        /// <summary>鼠标按下时候的位置</summary>
        private Point m_MouseDownPos;
        private int move;
        /// <summary>
        /// 用于保存是否展开的状态 用key作为容器,刷新前清除容器,需要保证键值唯一
        /// </summary>
        private Dictionary<string, bool> mNodesStatusDic = new Dictionary<string, bool>();
        public int ItemHeight
        {
            get
            {
                return mItemHeight;
            }
            set
            {
                mItemHeight = Math.Max(value, 5);
                VscrollBar.SmallChange = mItemHeight;
                Refresh();
                //EnsureVisible(SelectItem.ModNo);
            }
        }

        public UserControl1()
        {
            InitializeComponent();
            mProj = new Project();
            mProj.mChangeEvent += ChangeEvents;
            mItemDragEnabled = true;
            mTreeView = new TreeView();
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true); // 禁止擦除背景.
            SetStyle(ControlStyles.DoubleBuffer, true); // 双缓冲
            VscrollBar.Height = base.Height;
        }
        private TreeNodeCollection Nodes
        {
            get
            {
                if (mTreeView == null)
                {
                    return null;
                }
                return mTreeView.Nodes;
            }
        }
        /// <summary>获取结构树的展开状态</summary>
        private void GetTreeNodesStatus(TreeNodeCollection nodes)
        {
            try
            {
                foreach (TreeNode node in nodes)
                {
                    if (node.IsExpanded /*|| mCurModName == node.Text*/)//当鼠标位置的模块是折叠的 由于新加,则展开
                    {
                        mNodesStatusDic.Add(node.Text, true);
                    }
                    else
                    {
                        mNodesStatusDic.Add(node.Text, false);
                    }
                    GetTreeNodesStatus(node.Nodes);
                }
            }
            catch { }
        }
        /// <summary>设置结构树状态</summary>
        private void SetTreeNodesStatus(TreeNodeCollection nodes)
        {
            //if (自动折叠ToolStripMenuItem.Checked)
            //{
            //    foreach (TreeNode node in nodes)
            //    {
            //        node.Expand();
            //        node.ExpandAll();
            //        SetTreeNodesStatus(node.Nodes);
            //    }
            //}
            //else
            {
                foreach (TreeNode node in nodes)
                {
                    //node.Collapse();
                    if (!mNodesStatusDic.ContainsKey(node.Text)) //20210522 fly加
                        return;
                    if (mNodesStatusDic[node.Text])//true 展开 20210522 fly加
                    {
                        node.Expand();
                    }
                    else
                    {
                        node.Collapse();
                    }
                    SetTreeNodesStatus(node.Nodes);
                }
            }
        }

        public void ChangeEvents(object sender, EventArgs e)
        {
            int sfcIndex = -1;
            mNodesStatusDic.Clear();
            GetTreeNodesStatus(Nodes);
            Nodes.Clear();
            Stack<ModFlowItem> s_ParentItemStack = new Stack<ModFlowItem>();//将父节点放入栈容器 
            foreach (ModuleParam info in  mProj.ModuleInfo)
            {
                if (info == null)
                    break;
                sfcIndex++;
                ModFlowItem NodeItem = new ModFlowItem(info, sfcIndex);
                if (info.ModuleName.StartsWith("结束") || //是结束则 取消栈里对应的if
                     info.ModuleName.StartsWith("否则") ||
                     info.ModuleName.StartsWith("坐标补正结束") ||
                     info.ModuleName.StartsWith("循环结束"))  // 
                {
                    s_ParentItemStack.Pop();
                }
                if (s_ParentItemStack.Count > 0)
                {
                    ModFlowItem parentItem = s_ParentItemStack.Peek();
                    parentItem.Nodes.Add(NodeItem);
                }
                else
                {
                    Nodes.Add(NodeItem);//根目录
                }
                                    //判断当前节点是否是父节点开始
                if (Regex.IsMatch(info.ModuleName, "如果[0-9]*$") ||
                    Regex.IsMatch(info.ModuleName, "否则[0-9]*$") ||
                    Regex.IsMatch(info.ModuleName, "坐标补正[0-9]*$") ||
                    Regex.IsMatch(info.ModuleName, "文件夹[0-9]*$") ||
                    Regex.IsMatch(info.ModuleName, "循环开始[0-9]*$")
                 )
                {
                    //NodeItem.Expand();
                    s_ParentItemStack.Push(NodeItem);
                }
                else if (info.PluginName == "文件夹结束" && Regex.IsMatch(info.ModuleName, "文件夹结束[0-9]*$"))   //文件夹结束也放入到文件夹中
                {
                    s_ParentItemStack.Pop();
                }
            }
            SetTreeNodesStatus(Nodes);
        }
        public bool RefreshEnabled { get; set; } = true;
        protected override void OnResize(EventArgs e)
        {
            base.OnResize(e);
            if (mBuff != null)
            {
                mBuff.Dispose();
            }
            mBuff = new Bitmap(Math.Max(base.Width, 1), Math.Max(base.Height, 1));
            RefreshEnabled = true;
            Refresh();
        }

        SolidBrush brush = new SolidBrush(Color.Red);
        SolidBrush brush1 = new SolidBrush(Color.Black);
        protected override void OnPaint(PaintEventArgs e)
        {
            if (DesignMode)
            {
                return;
            }
            int left = 0;//
            int width = this.Width;
            Font font = new Font("宋体", 10F, FontStyle.Regular);
            try
            {
                if (mBuff != null)
                {
                    int num;
                    int num4 = 0;
                    int top = num = -VscrollBar.Value;
                    ModFlowItem.ControlWidth = base.Width - (VscrollBar.Visible ? VscrollBar.Width : 0);
                    using (Graphics graphics = Graphics.FromImage(mBuff))
                    {
                        graphics.FillRectangle(new SolidBrush(Color.LightCyan), new Rectangle(0, 0, base.Width, base.Height));//PowderBlue
                        string mSpaceKey = "";   
                        if (Width > 160)
                        {
                            for (int i = 0; i < Width - 190; i += 6)
                            {
                                mSpaceKey += " ";
                            }
                        }
                        //对每个模块绘制
                        foreach (ModFlowItem item in Nodes)
                        {
                            if (item != null) { item.PaintItem(graphics, ref left, ref top, base.Width, mItemHeight, 0, mSpaceKey, ref num4, false); }
                        }
                        if (Nodes.Count > 0)
                        {
                            using (Pen pen2 = new Pen(Color.Blue))
                            {
                                graphics.DrawLine(pen2, 8, top, ModFlowItem.ControlWidth, top);//底部分割线
                            }
                        }
                        e.Graphics.DrawImage(mBuff, 0, VscrollBar.Top);
                    }
                    if ((top + VscrollBar.Value) < VscrollBar.Height)
                    {
                        VscrollBar.Value = 0;
                        VscrollBar.Visible = false;
                    }
                    else
                    {
                        VscrollBar.Visible = true;
                    }
                    VscrollBar.Maximum = Math.Max((top - num) + mItemHeight, 0);
                    VscrollBar.LargeChange = VscrollBar.Height;
                    VscrollBar.SmallChange = mItemHeight;
                }
            }
            catch (OutOfMemoryException)
            {
                // SharedClass.ExceptionOutOfMemory(exception);
            }
            base.OnPaint(e);
        }
        /// <summary>
        /// TODO:滚轮事件
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseWheel(MouseEventArgs e)
        {
            if (((base.Visible) && (VscrollBar.Visible)))
            {
                if (e.Delta > 0)
                {
                    if (VscrollBar.Value - mItemHeight >= VscrollBar.Minimum)
                    {
                        VscrollBar.Value -= mItemHeight;
                    }
                }
                if (e.Delta < 0)
                {
                    if (VscrollBar.Value + Height < VscrollBar.Maximum)
                    {
                        VscrollBar.Value += mItemHeight;
                    }
                }
            }
            base.OnMouseWheel(e);
        }
        private void ItemSelectDrag(ModFlowItem item)
        {
            if (mItemDragEnabled)
            {
                ModFlowItem.dragList = true;
                ModFlowItem.m_DragFromUnitNo = item.ModNo;
                Cursor = Cursors.Hand;
            }
            UnSelectAllNode(Nodes);
            item.IsSelected = true;
            //if (PluginService.g_PluginDic.ContainsKey(mUiFrom.mModuleParam.PluginName))//20210522 fly 加
            {
                gCursor1.gText = mIsNowSelectedItem.mModuleParam.ModuleName;
                gCursor1.gEffect = gCursor.eEffect.Move;
                //if (PluginService.g_PluginDic[mUiFrom.mModuleParam.PluginName].IconImage != null)
                //{ gCursor1.gImage = PluginService.g_PluginDic[mUiFrom.mModuleParam.PluginName].IconImage.ToBitmap(); }
                gCursor1.gImage = mIsNowSelectedItem.mModuleParam.Icon.ToBitmap();
                gCursor1.gType = gCursor.eType.Both;
                gCursor1.MakeCursor();
            }
        }
        /// <summary>
        /// TODO:鼠标按下
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            timer_VscrollBar.Enabled = true;
            m_MouseDownPos = new Point(e.X, e.Y);
            mUiFrom = mIsNowSelectedItem = GetNodeFromPosition(mTreeView.Nodes, e);
            if (mIsNowSelectedItem != null)
            {
                ModFlowItem.m_DragToUnitNo = -1;
                switch (mIsNowSelectedItem.HitCheck(e))
                {
                    case CheckArea.Space:
                        ItemSelectDrag(mIsNowSelectedItem);
                        break;
                    case CheckArea.Remarks:
                        ItemSelectDrag(mIsNowSelectedItem);
                        break;
                }
            }
            Refresh();
            base.OnMouseDown(e);
        }
        protected override void OnMouseMove(MouseEventArgs e)
        {
            Point curDownPos = new Point(e.X, e.Y);//当前位置
            if (ModFlowItem.dragList &&  Math.Abs(m_MouseDownPos.Y - curDownPos.Y) > 30)
            {
                Cursor.Current = gCursor1.gCursor;
            }
            if (ModFlowItem.dragList)
            {
                ModFlowItem mModFlowItem = null;
                if (e != null)
                {
                    mModFlowItem = GetNodeFromPosition(mTreeView.Nodes, e);
                }
                if (mModFlowItem != null)
                {
                    ModFlowItem.m_DragToUnitNo = mModFlowItem.ModNo;
                    //Debug.WriteLine("mModFlowItem.ModNo:" + ModFlowItem.m_DragToUnitNo);
                }

                if (e.Y < (VscrollBar.Top + mItemHeight))
                {
                    move = -mItemHeight;
                }
                else if (e.Y > (base.Height - mItemHeight))
                {
                    move = mItemHeight;
                }
                else
                {
                    move = 0;
                }
                 Refresh();
            }
            base.OnMouseMove(e);
        }
        /// <summary>
        /// TODO:模块创建
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            Cursor = Cursors.Default;
            timer_VscrollBar.Enabled = false;
            //获取当前鼠标位置的模块
            ModFlowItem MousePos = GetNodeFromPosition(mTreeView.Nodes, e);
            if ((ModFlowItem.dragList /*|| ModFlowItem.dragInNew*/) && mUiFrom != null) //拖拽过程中
            {
                if (MousePos.ModNo != mUiFrom.ModNo)
                {
                    string mCurModName = MousePos.mModuleParam.ModuleName;
                    bool isNext = true;
                    if (mUiFrom.ModNo != -1)//-1表示新建的 //移动模块
                    {
                        mProj.ChangePos(mUiFrom.mModuleParam.ModuleName, mCurModName, isNext, null, null);
                    }
                    //else
                    //{
                    //    mProj.AddModObj(mCurModName, mUiFrom.mModuleParam, isNext);
                    //}
                }
            }
            ModFlowItem.dragList = false;
            if (MousePos != null)
            {
                if (MousePos.HitCheck(e) == CheckArea.Icon)
                {
                    if (MousePos.UnitType == UnitType.Folder)
                    {
                        MousePos.Toggle();
                    }
                }
            }
            Refresh();
            base.OnMouseUp(e);
        }
        private ModFlowItem GetLastNode(TreeNodeCollection Nodes)
        {
            ModFlowItem item = null;
            if (Nodes.Count > 0)
            {
                item = (ModFlowItem)Nodes[Nodes.Count - 1];
                if (item.Nodes.Count > 0)
                {
                    item = GetLastNode(Nodes[Nodes.Count - 1].Nodes);
                }
            }
            return item;
        }
        private void UnSelectAllNode(TreeNodeCollection Nodes)
        {
            foreach (ModFlowItem item in Nodes)
            {
                item.IsSelected = false;
                if (item.Nodes.Count > 0)
                {   //取消全选
                    UnSelectAllNode(item.Nodes);
                }
            }
        }
        /// <summary>TODO:当前鼠标位置的模块 </summary>
        /// <param name="Nodes"></param>
        private ModFlowItem GetNodeFromPosition(TreeNodeCollection Nodes, MouseEventArgs e)
        {
            ModFlowItem nodeFromPosition = GetNodeFromPositionIteration(Nodes, e);
            if (nodeFromPosition == null)
            {
                nodeFromPosition = GetLastNode(Nodes);
            }
            return nodeFromPosition;
        }
        private ModFlowItem GetNodeFromPositionIteration(TreeNodeCollection Nodes, MouseEventArgs e)
        {
            ModFlowItem nodeFromPosition = null;
            foreach (ModFlowItem item2 in Nodes)
            {
                int num = item2.Top + VscrollBar.Top;
                if (((num < e.Y) && ((num + mItemHeight) > e.Y)) && ((item2.Left < e.X) && (e.X < base.Width)))
                {
                    return item2;
                }
                if ((item2.UnitType == UnitType.Folder) && item2.IsExpanded)
                {
                    nodeFromPosition = GetNodeFromPositionIteration(item2.Nodes, e);
                }
                if (nodeFromPosition != null)
                {
                    return nodeFromPosition;
                }
            }
            return nodeFromPosition;
        }
        protected override void WndProc(ref Message m)
        {
            if (m.Msg == 0x0014) // 禁掉清除背景消息WM_ERASEBKGND
                return;
            base.WndProc(ref m);
        }

        private void VscrollBar_ValueChanged(object sender, EventArgs e)
        {
            base.SuspendLayout();
            int num = VscrollBar.Value;
            num -= num % ItemHeight;
            VscrollBar.Value = num;
            base.ResumeLayout(false);
            base.Refresh();
        }
        public void changeScore()
        {
            VscrollBar.Value = VscrollBar.Value+100;
            Refresh();
        }

        private void timer_VscrollBar_Tick(object sender, EventArgs e)
        {
            if (move != 0)
            {
                VscrollBar.Value = Math.Max(0, Math.Min((int)(VscrollBar.Maximum - (base.Height)), (int)(VscrollBar.Value + move)));
                Debug.WriteLine($"max:{VscrollBar.Maximum};;langecharge{VscrollBar.LargeChange},range{VscrollBar.Maximum- VscrollBar.LargeChange},value{VscrollBar.Value}");
            }
        }
    }
}
